﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace iWare.Wms.Application.Service.PDA
{
    /// <summary>
    /// 标签打印服务
    /// </summary>
    [Route("api/LabelPrinting")]
    [ApiDescriptionSettings("PDA", Name = "LabelPrinting", Order = 1)]

    public class LabelPrintingService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WareArea, MasterDbContextLocator> _wareAreaRep; //所属库区
        private readonly IRepository<WareMaterial, MasterDbContextLocator> _wareMaterialRep; //物料仓储
        private readonly IRepository<WareMaterialWarehouse, MasterDbContextLocator> _wareMaterialWarehouseRep; //品号仓库仓储
        private readonly IRepository<WareContainer, MasterDbContextLocator> _wareContainerRep; //容器仓储
        private readonly IRepository<WareLocation, MasterDbContextLocator> _wareLocationRep; //库位仓储
        private readonly IRepository<WareStock, MasterDbContextLocator> _wareStockRep; //库存仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="wareAreaRep"></param>
        /// <param name="wareMaterialRep"></param>
        /// <param name="wareMaterialWarehouseRep"></param>
        /// <param name="wareContainerRep"></param>
        /// <param name="wareLocationRep"></param>
        /// <param name=""></param>
        public LabelPrintingService(
             IRepository<WareArea, MasterDbContextLocator> wareAreaRep,
             IRepository<WareMaterialWarehouse, MasterDbContextLocator> wareMaterialWarehouseRep,
             IRepository<WareMaterial, MasterDbContextLocator> wareMaterialRep,
             IRepository<WareContainer, MasterDbContextLocator> wareContainerRep,
             IRepository<WareLocation, MasterDbContextLocator> wareLocationRep
        )
        {
            _wareAreaRep = wareAreaRep;
            _wareMaterialRep = wareMaterialRep;
            _wareMaterialWarehouseRep = wareMaterialWarehouseRep;
            _wareContainerRep = wareContainerRep;
            _wareLocationRep = wareLocationRep;
        }
        #endregion

        /// <summary>
        /// 根据条件模糊查询容器
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetSystemConatiner")]
        public async Task<List<GenerateVirtuallyContainerOutput>> GetSystemConatiner([FromQuery] GetSystemConatinerInput input)
        {
            return await _wareContainerRep.DetachedEntities.Where(t => t.Code.Contains(input.ConatinerCode))
                .ProjectToType<GenerateVirtuallyContainerOutput>().Take(10).ToListAsync();
        }

        /// <summary>
        /// 生成虚拟容器信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("GenerateVirtually")]
        public async Task<GenerateVirtuallyContainerOutput> GenerateVirtuallyContainer([FromQuery] GenerateVirtuallyContainerInput input)
        {
            Random random = new Random();
            string strRandom = random.Next(10000, 99999).ToString(); //生成编号 

            // 定义是立体还是平库容器
            var areaType = string.Empty;

            var wareArea = await _wareAreaRep.FirstOrDefaultAsync(z => z.Id == input.AreaID);
            if (wareArea != null && wareArea.AreaName.Contains("立体库")) areaType = "L-";
            else if (wareArea != null && wareArea.AreaName.Contains("平库")) areaType = "P-";
            else areaType = "";

            var isExists = await _wareContainerRep.AnyAsync(z => z.Code == areaType + input.Parameter1 + input.Parameter2 + strRandom && z.AreaID == input.AreaID);
            if (isExists) strRandom = random.Next(10000, 99999).ToString(); //生成编号 

            return new GenerateVirtuallyContainerOutput
            {
                AreaID = input.AreaID,
                Code = areaType == "" ? input.Parameter1 + input.Parameter2 + strRandom : areaType + input.Parameter1 + input.Parameter2 + strRandom, //容器编号
                Parameter1 = input.Parameter1, //容器种类
                Parameter2 = input.Parameter2 //容器材质
            };
        }

        /// <summary>
        /// 确认生成虚拟容器
        /// </summary>
        /// <returns></returns>
        [HttpPost("ConfirmGenerate")]
        public async Task ConfirmGenerateContainer([FromBody] ConfimGenerateContainerInput input)
        {
            var isExists = await _wareContainerRep.AnyAsync(z => z.Code == input.Code && z.AreaID == input.AreaID);
            if (isExists) throw Oops.Oh("数据已存在");

            var wareContainer = input.Adapt<WareContainer>();
            wareContainer.IsVirtual = YesOrNot.Y;
            await _wareContainerRep.InsertAsync(wareContainer);
        }

        /// <summary>
        /// 根据条件模糊查询容器
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetSystemLocation")]
        public async Task<List<GenerateVirtuallyLocationOutput>> GetSystemLocation([FromQuery] GetSystemLocationInput input)
        {
            return await _wareLocationRep.DetachedEntities.Where(t => t.Code.Contains(input.LocationCode))
                .ProjectToType<GenerateVirtuallyLocationOutput>().Take(10).ToListAsync();
        }

        /// <summary>
        /// 生成虚拟库位信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("GenerateVirtuallyLocation")]
        public async Task<GenerateVirtuallyLocationOutput> GenerateVirtuallyLocation([FromQuery] GenerateVirtuallyLocationInput input)
        {
            Random random = new Random();
            string strRandom = random.Next(100, 999).ToString(); //生成编号 

            // 根据所属库区ID查询库区信息
            var wareArea = await _wareAreaRep.FirstOrDefaultAsync(z => z.Id == input.AreaID);
            if (wareArea == null) throw Oops.Oh("所属库区信息不存在!");

            string wareOne = "W"; //所属企业
            string wareTwo = "1"; //所属厂区
            string wareThree = string.Empty; //所属库区
            int aisle = 1; //巷道
            if (wareArea.AreaName.Contains("立")) wareThree = "L";
            else if (wareArea.AreaName.Contains("平") || wareArea.AreaName.Contains("普通")) wareThree = "P";
            else if (wareArea.AreaName.Contains("公共")) wareThree = "G";
            else wareThree = "ZQ";
            int rowNo = Convert.ToInt32(strRandom.Substring(0, 1)); //排
            int columnNo = Convert.ToInt32(strRandom.Substring(1, 1)); //列
            int layerNo = Convert.ToInt32(strRandom.Substring(2, 1)); //层

            var isExists = await _wareLocationRep.AnyAsync(z => z.Code == wareOne + wareTwo + wareThree + rowNo + columnNo + layerNo && z.AreaID == input.AreaID);
            if (isExists) strRandom = random.Next(1000, 999).ToString(); //生成编号 

            return new GenerateVirtuallyLocationOutput
            {
                AreaID = input.AreaID,
                Code = wareOne + wareTwo + wareThree + aisle + rowNo + columnNo + layerNo, //库位编号
                WareOne = wareOne,
                WareTwo = wareTwo,
                WareThree = wareThree,
                RowNo = rowNo,
                ColumnNo = columnNo,
                LayerNo = layerNo,
            };
        }

        /// <summary>
        /// 确认生成虚拟库位
        /// </summary>
        /// <returns></returns>
        [HttpPost("ConfirmGenerateLocation")]
        public async Task ConfirmGenerateLocation([FromBody] ConfimGenerateLocationInput input)
        {
            var isExists = await _wareLocationRep.AnyAsync(z => z.Code == input.Code && z.AreaID == input.AreaID);
            if (isExists) throw Oops.Oh("数据已存在!");

            // 根据所属库区ID查询库区信息
            var wareArea = await _wareAreaRep.FirstOrDefaultAsync(z => z.Id == input.AreaID);
            if (wareArea == null) throw Oops.Oh("所属库区信息不存在!");

            var wareLocation = input.Adapt<WareLocation>();
            wareLocation.WareOne = "W";
            wareLocation.WareTwo = "1";
            if (wareArea.AreaName.Contains("立")) wareLocation.WareThree = "L";
            else if (wareArea.AreaName.Contains("平") || wareArea.AreaName.Contains("普通")) wareLocation.WareThree = "P";
            else if (wareArea.AreaName.Contains("公共")) wareLocation.WareThree = "G";
            else if (wareLocation.WareThree.Contains("装配")) wareLocation.WareThree = "ZQ";
            else wareLocation.WareThree = "XN";
            wareLocation.Aisle = 1; //巷道
            wareLocation.DeepcellNo = 1; //深号
            wareLocation.Code = wareLocation.WareOne + wareLocation.WareTwo + wareLocation.WareThree;
            wareLocation.IsVirtual = YesOrNot.Y;

            await _wareLocationRep.InsertAsync(wareLocation);
        }

        /// <summary>
        /// 物料标签打印查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("MaterialPrint")]
        public async Task<PDAMaterialPrintOutput> MaterialPrint([FromQuery] PDAMaterialPrintInput input)
        {
            var wareMaterial = await _wareMaterialRep.FirstOrDefaultAsync(u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"));
            if (wareMaterial == null) throw Oops.Oh("物料信息不存在");

            var projectCodeList = await _wareMaterialWarehouseRep.DetachedEntities.Where(z => z.Code == wareMaterial.Code).Select(z => z.Name).Distinct().ToListAsync();

            var returnMaterial = wareMaterial.Adapt<PDAMaterialPrintOutput>();
            returnMaterial.ProjectCode = projectCodeList;
            returnMaterial.Xuhao = "0001";
            returnMaterial.ManufactureDate = DateTimeOffset.Now; //入库时间

            return returnMaterial;
        }
    }
}
